#include "fsmc.h"
#include "SPI_INIT.h"
#define FSMC_RAM    *(__IO uint16_t *) (0x6C000002)    	//地址寄存器
#define FSMC_REG    *(__IO uint16_t *) (0x6C000000)	 	//指令寄存器

void write_cmd(unsigned short cmd)
{	
	FSMC_REG = cmd;	
}

void Write_DATA(unsigned short data_code )
{	
	FSMC_RAM = data_code;
}

void MCU_2828_write_CMD(u8 channel,u16 cmd)
{	
	u16 i = 1000;
    SPI_CS_Select(channel,0);
    FSMC_REG = cmd;
    while(i--);
    i = 1000;	
    SPI_CS_Select(channel,1);
    while(i--); 	
}

void MCU_2828_write_CMD_NOCS(u16 cmd)
{	
    FSMC_REG = cmd;
}


void MCU_2828_Write_Data(u8 channel,u16 data_code )
{	
	u16 i = 1000;	
    SPI_CS_Select(channel,0);
    FSMC_RAM = data_code;
    while(i--);
    i = 1000;		
    SPI_CS_Select(channel,1);
    while(i--); 	
}


u16 MCU_2828_Read_Data(u8 channel)
{	
    u16 i = 1000;
    u16  data_code;
    SPI_CS_Select(channel,0);
    data_code = FSMC_RAM;
    while(i--);
    i = 1000;
    SPI_CS_Select(channel,1);
    while(i--);  
    return data_code;
    
}

//fsmc 发送纯色画面，DEBUG模式使用
void FSMC_Pure_colour(u32 Color)
{
	write_cmd(0x5678);						//将OLED时序数据发送到FPGA
	write_cmd((u16)(((OLED.RGBMode==2)?3:1)<<8)|((Color&0xff0000)>>16));
	write_cmd((u16)(Color&0x00ffff));
	write_cmd(0x8765);
}


void FSMC_Pure_colour_Partial_Display(u16 x0,u16 x1,u16 y0,u16 y1, u32 PartialColor, u32 BackColor)
{
	write_cmd(0x6789);						//将OLED时序数据发送到FPGA
	write_cmd((u16)(((OLED.RGBMode==2)?4:4)<<8)|((PartialColor&0xff0000)>>16));
	write_cmd((u16)(PartialColor&0x00ffff));
	write_cmd((u16)((BackColor&0xffff00)>>8));
	write_cmd((u16)(BackColor&0x0000ff));
	write_cmd(x0);
	write_cmd(x1);
	write_cmd(y0);	
	write_cmd(y1);		
	write_cmd(0x9876);
}


//fsmc 
void FSMC_BMP_NUM(u8 BMP_NUM)
{
	write_cmd(0x4567);						//将OLED时序数据发送到FPGA
    delay_us(4);
	//write_cmd(BMP_NUM);	  //
	write_cmd((((OLED.RGBMode==2)?2:0)<<8) |BMP_NUM);	  //
    delay_us(4);
	write_cmd(0x7654);	
    delay_us(4);
}

void FSMC_OLED_Parameter(u32* buf,u8 SigMode)
{
    write_cmd(0x1234);						//将OLED时序数据发送到FPGA
    for(i = 0;i < 4;i ++)
    {
        write_cmd(buf[i+8]>>16);				//	0:H_PIXEL	1:H_B	2:H_F	3:H_S	4:高8(单双6,8)
        write_cmd(buf[i+8]);						//	0:V_PIXEL	1:V_B	2:V_F	3:V_S	4:无效
    }
    write_cmd(((buf[12]>>16)&0xff00)+((SigMode == Mipi_Mode) ? 0x00 : 0x01));				//	高8(单双6,8)
    write_cmd(buf[14]>>24);				//	无效  0:video  1:Command
    write_cmd(0x4321);			  
}

void FSMC_Open(u16 Init_Mode)
{
	write_cmd(0x2345);						
	write_cmd(Init_Mode);	
	write_cmd(0x5432);	
}

void FSMC_IO_init(void)
{	
	GPIO_InitTypeDef GPIO_InitStructure; 
	FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
	FSMC_NORSRAMTimingInitTypeDef  p,p1; 
    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG| RCC_AHB1Periph_GPIOF , ENABLE);
	RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);	

	GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);		
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);	
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource10, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
		GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
    
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource7 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource8 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource9 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource10 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource11 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource12 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource13 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource14 , GPIO_AF_FSMC);
	GPIO_PinAFConfig(GPIOE, GPIO_PinSource15 , GPIO_AF_FSMC);
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7 |	GPIO_Pin_8  | GPIO_Pin_9  | GPIO_Pin_10 | GPIO_Pin_11|
		GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_Init(GPIOE, &GPIO_InitStructure);
    
    GPIO_PinAFConfig(GPIOG, GPIO_PinSource12, GPIO_AF_FSMC);
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_12;
	GPIO_Init(GPIOG, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_FSMC);
	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0;
	GPIO_Init(GPIOF, &GPIO_InitStructure);

    p.FSMC_AddressSetupTime = 0x04;
    p.FSMC_AddressHoldTime = 0x04;
    p.FSMC_DataSetupTime = 0x0a;
    p.FSMC_BusTurnAroundDuration = 0x00;
    p.FSMC_CLKDivision = 0x04;
    p.FSMC_DataLatency = 0x00;
    p.FSMC_AccessMode = FSMC_AccessMode_A;

    p1.FSMC_AddressSetupTime = 0x00;
    p1.FSMC_AddressHoldTime = 0x00;
    p1.FSMC_DataSetupTime = 0x50;
    p1.FSMC_BusTurnAroundDuration = 0x00;
    p1.FSMC_CLKDivision = 0x08;
    p1.FSMC_DataLatency = 0x00;
    p1.FSMC_AccessMode = FSMC_AccessMode_A;

	FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;
	FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
	FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
	FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
	FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
	FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
	FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait= FSMC_AsynchronousWait_Disable;
	FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
	FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
	FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
	FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
	FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
	FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
	FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p1;
	FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
	FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
	FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);	
}

